为什么需要将自己创建的列(例如select 1 as "number")放在 MySQL 之后HAVING而不是WHEREMySQL 中?
select 1 as "number"
HAVING
WHERE
并且有什么缺点而不是做WHERE 1(写整个定义而不是列名)?
WHERE 1
关于这个问题的所有其他答案都没有触及关键点。
假设我们有一张表:
CREATE TABLE `table` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `value` int(10) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `value` (`value`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
并且有 10 行 id 和 value 从 1 到 10:
INSERT INTO `table`(`id`, `value`) VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(10, 10);
尝试以下 2 个查询:
SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows
您将得到完全相同的结果,您可以看到该HAVING子句可以在没有 GROUP BY 子句的情况下工作。
区别如下:
SELECT `value` v FROM `table` WHERE `v`>5;
上述查询将引发错误:错误 #1054 - ‘where 子句’中的未知列 ‘v’
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
WHERE子句允许条件使用任何表列,但不能使用别名或聚合函数。 HAVING子句允许条件使用选定 (!) 列、别名或聚合函数。
这是因为WHERE子句在选择之前过滤数据,但HAVING子句在选择之后过滤结果数据。
WHERE因此,如果表中有很多行,则将条件放在子句中会更有效。
尝试EXPLAIN查看关键区别:
EXPLAIN
EXPLAIN SELECT `value` v FROM `table` WHERE `value`>5; +----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+ | 1 | SIMPLE | table | range | value | value | 4 | NULL | 5 | Using where; Using index | +----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+ EXPLAIN SELECT `value` v FROM `table` having `value`>5; +----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+ | 1 | SIMPLE | table | index | NULL | value | 4 | NULL | 10 | Using index | +----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
您可以看到WHERE或HAVING使用索引,但行不同。